#include <Wire.h>
#include <dummy.h>
#include "Global/globalVars.hpp"
#include "TempControl/fanSpeedMonitor.hpp"
#include "TempControl/powerDrive.hpp"
#include "TempControl/tempUpdate.hpp"
#include "main/tempCtrlService.hpp"
#include "Config/configRL.hpp"
#include "main/onlineLoop.hpp"
#include "Interface/parseCMD.hpp"
#include "LedControl/ledControl.h"

// compiled with: esp32-arduino 2.0.4

// note on hardware version
// control: 23.08.22, adc 23.09.13, TEC drive ?, Res driver 23.09.12 uses 100k/4250 NTC
// control 24.05.22 (labeled 24.05.22), adc 24.05.22, ? uses 4.7k for 10k 3950 NTC
void setup()
{
	Serial.begin(115200);
	Wire.setTimeOut(10);
	//  ConfigRL::load();
	GlobalVars::init();
	FanSpeedMonitor::init();
	PowerDrive::init();
	LedControl::init();
	while (!Serial)
	{
	}

	if (TempReader::init())
	{
		Serial.println(F("Temp reader ok"));
		GlobalVars::plateTemp.readingVal = TempReader::readPlateTmp();
		GlobalVars::plateTemp.readingTimeMs = millis();
		Serial.println("Initial plate temp: " + String(GlobalVars::plateTemp.readingVal));
		GlobalVars::sampleLeftTemp.readingVal = TempReader::readSampleLeftTmp();
		GlobalVars::sampleLeftTemp.readingTimeMs = millis();
		Serial.println("Initial sample left side temp: " + String(GlobalVars::sampleLeftTemp.readingVal));
		GlobalVars::sampleRightTemp.readingVal = TempReader::readSampleRightTmp();
		GlobalVars::sampleRightTemp.readingTimeMs = millis();
		Serial.println("Initial sample right side temp: " + String(GlobalVars::sampleRightTemp.readingVal));
		GlobalVars::pumpTemp.readingVal = TempReader::readPumpTmp();
		GlobalVars::pumpTemp.readingTimeMs = millis();
		Serial.println("Initial pump temp: " + String(GlobalVars::pumpTemp.readingVal));
		GlobalVars::containerTemp.readingVal = TempReader::readContainerTmp();
		GlobalVars::containerTemp.readingTimeMs = millis();
		Serial.println("Initial container temp: " + String(GlobalVars::containerTemp.readingVal));
		GlobalVars::surroundingTemp.readingVal = TempReader::readSurroundingTmp();
		GlobalVars::surroundingTemp.readingTimeMs = millis();
		Serial.println("Initial surrounding temp: " + String(GlobalVars::surroundingTemp.readingVal));
		GlobalVars::coreTemp.readingVal = TempReader::readInternalTmp();
		GlobalVars::coreTemp.readingTimeMs = millis();
		Serial.println("Initial core temp: " + String(GlobalVars::coreTemp.readingVal));
	}
	else
	{
		Serial.println(F("Temp reader failed"));
	}

	TempCtrlService::init();
	//Serial.println("MetaDataRL");
	ConfigRL::MetaDataRL::load();
	//Serial.println("ThermalModelMetricsRL");
	ConfigRL::ThermalModelMetricsRL::load();
	ConfigRL::ChangeTempSpeedRL::load();
	//Serial.println("HeadUpCurveRL");
	ConfigRL::HeadUpCurveRL::load();
	//Serial.println("HeadHoldCurveRL");
	ConfigRL::HeadHoldCurveRL::load();
	//Serial.println("CoolDownCurveRL");
	ConfigRL::CoolDownCurveRL::load();
	//Serial.println("CoolHoldCurveRL");
	ConfigRL::CoolHoldCurveRL::load();
	//Serial.println("StartUpModeRL");
	// PowerDrive::setChannelPercent(0, 50);
	// PowerDrive::setChannelPercent(1, 50);

	ConfigRL::StartUpModeRL::load();

	//Serial.println("applyStartUpConfig");
	OLLoop::applyStartUpConfig();

	interrupts();
}

// the loop function runs over and over again forever
void loop()
{
	if (Serial.available())
	{
		const char* buffer = OLLoop::readInput(Serial);
		GlobalVars::heartBeatUpdate();
		// String cmd = Serial.readStringUntil('\n');
		parseCMD(buffer);
	}

	OLLoop::onlineLoop();
	LedControl::service();
}
